home *** CD-ROM | disk | FTP | other *** search
/ PC-Blue - MS DOS Public Domain Library / PC-Blue MS-DOS Public Domain Library - NYACC.iso / vol309 / jdutil.arc / LS.ASM < prev    next >
Encoding:
Assembly Source File  |  1986-09-04  |  32.5 KB  |  867 lines

  1.         TITLE LS - SORTED DIRECTORY PROGRAM
  2.         PAGE  55,132
  3. ;************************************************************************
  4. ;       THIS PROGRAM DISPLAYS A SORTED DIRECTORY WITH FILE SIZES.
  5. ;       IT REQUIRES MSDOS VERSION 2 OR HIGHER.
  6. ;
  7. ;       usage:  LS/A/L afn
  8. ;               /A (optional) includes hidden and system files
  9. ;               /L (optional) shows date, time, file size in bytes
  10. ;               afn may contain * and ?: e.g. "LS PROG?.*"
  11. ;
  12. ;    BY: JON DART
  13. ;        DEPARTMENT OF ANTHROPOLOGY
  14. ;        UCSD C-001
  15. ;        LA JOLLA, CA 92093
  16. ;
  17. ;    Version 1.6, 05-Jul-86 fixes sometime loss of top display line.
  18. ;             Now accepts - as well as / for switches.
  19. ;             Also modified to assemble under MASM 4.0.
  20. ;       Version 1.5, 04-May-86 fixes clear screen routine
  21. ;       Version 1.4, 17-Jan-86 UTIL and CONSOLE made external modules,
  22. ;                    adds FIXPATH function
  23. ;       Version 1,3, 07-Nov-85 /L option added
  24. ;       Version 1.2, 03-Nov-85 fixes bug in size function
  25. ;       Version 1.1, 18-Oct-85
  26. ;
  27. ;   TO BUILD LS.EXE:
  28. ;    MASM LS,LS,NUL,NUL
  29. ;    LINK LS,LS,NUL,ASM -C1200 -DO
  30.  
  31.     IF2
  32.     %OUT PASS 2
  33.     ENDIF
  34.  
  35. TRUE    EQU     1
  36. FALSE   EQU     0
  37. IBM     EQU     TRUE                    ;TRUE IF IBM-COMPATIBLE AT BIOS LEVEL
  38. BIOS    EQU     10H                     ;BIOS INTERRUPT FOR VIDEO FUNCTIONS
  39. MAXFILES EQU    512                     ;MAX # OF FILES
  40. NCOLUMN EQU     4                       ;# OF COLUMNS TO DISPLAY (SHORT MODE)
  41. MAXLINES EQU    23                      ;# LINES ON SCREEN FOR FILE DISPLAY
  42.     IF    IBM
  43. FENCE    EQU    179            ;VERTICAL BAR CHAR. (IBM ONLY)
  44.     ELSE
  45. FENCE   EQU     '|'                     ;BORDER BETWEEN COLUMNS
  46.     ENDIF
  47. K       EQU     1024                    ;1 K
  48.  
  49. M       EQU     BYTE PTR 0[BX]
  50.  
  51.         .XLIST
  52.         INCLUDE ASCII.DEF
  53.         INCLUDE MSDOS2.DEF
  54.     INCLUDE MACROS.DEF
  55.         .LIST
  56.  
  57. SETDS   MACRO
  58.         PUSH    DS
  59.         PUSH    AX
  60.         MOV     AX,DATA
  61.         MOV     DS,AX
  62.         POP     AX
  63.         ENDM
  64.  
  65. RESDS   MACRO
  66.         POP     DS
  67.         ENDM
  68.  
  69. PRINT    MACRO    DATA
  70.     SETDS
  71.     MOV    DX,OFFSET DATA
  72.     MOV    AH,CON_STRING_OUTPUT
  73.     INT    DOS
  74.     RESDS
  75.     ENDM
  76.  
  77. ;       DEFINE OFFSETS OF BUFFER AREAS (FROM ES):
  78.  
  79. FILNAM  EQU     0                       ;FILE NAME FROM COMMAND LINE
  80. SPATH   EQU     FILNAM+80               ;SEARCH PATH
  81. SPREFIX EQU     SPATH+80                ;SEARCH PREFIX (NOT USED)
  82. OUR_DTA EQU     SPREFIX+80              ;DISK TRANSFER ADDRESS, USED BY MSDOS
  83.                                         ;FUNCTIONS 4EH AND 4FH.
  84. ADDRLIST EQU    OUR_DTA+80H             ;HOLDS POINTERS TO INFO ON EACH FILE
  85. BUFFER  EQU     ADDRLIST+(2*MAXFILES)   ;HOLDS INFO ON EACH FILE, RETURNED BY
  86.                                         ;MSDOS FUNCTION 4EH OR 4FH.
  87. ENDBUF  EQU     BUFFER+(MAXFILES*22)
  88.  
  89. STACK   SEGMENT WORD STACK 'STACK'
  90.         DB 512 DUP (?)
  91. STACK   ENDS
  92.  
  93. ;*********************
  94. ; MEMORY DEFINITIONS *
  95. ;*********************
  96. ;
  97. DATA    SEGMENT BYTE PUBLIC 'DATA'
  98. AFLAG   DB      0                       ;SET <>0 IF /A
  99. LFLAG   DB      0                       ;SET <>0 IF /L
  100. DRIVE   DB      0                       ;DRIVE (0 FOR DEFAULT, 1 FOR A, ETC)
  101. VPAGE   DB      0                       ;VIDEO PAGE # (IBM ONLY)
  102. SCRSIZE DB      80                      ;SCREEN WIDTH (80 IS DEFAULT FOR NON-IBM)
  103. VMODE   DB      0                       ;DISPLAY MODE (IBM ONLY)
  104. ATTRIBUTES DB  00010001B                ;DEFAULT FILE ATTRIBUTES
  105. NUMFILES DW    0                        ;NUMBER OF FILES FOUND
  106. NEXTFREE DW    1 DUP (?)                ;ADDR. OF NEXT FREE SLOT IN BUFFER
  107. GAP     DW      0                       ;USED BY SORT ROUTINE
  108. TEMP    DW      0                       ;USED BY SORT ROUTINE
  109. MAXLINE DW      1 DUP (?)               ;NO. OF LINES TO DISPLAY
  110. MAXFILE DW      1 DUP (?)               ;MAX FILE TO SHOW
  111. MAXCOL  DB      1 DUP (?)               ;COLUMN WIDTH OF DISPLAY
  112. COLCOUNT DW     1 DUP (?)               ;COUNT OF COLUMNS DISPLAYED
  113. LINECOUNT DW    1 DUP (?)               ;COUNT OF LINES DISPLAYED
  114. FILECOUNT DW    1 DUP (?)               ;COUNT OF FILES DISPLAYED
  115. BASE    DW      1 DUP (?)               ;FIRST FILE TO SHOW
  116. USED    DQ      0                       ;COUNT OF FILE SPACE USED
  117. DEFAULT DB      '????????.???',0        ;DEFAULT FILE NAME
  118. LOSIZE  DW      1 DUP (?)               ;USED IN CALCULATING FREE SPACE
  119. MSG1    DB      CR,LF,'Bad switch: '
  120. BADSW   DB      1 DUP (?)
  121.         DB      CR,LF,'$'
  122. MSG2    DB      CR,LF,'No matching files.',CR,LF,'$'
  123. MSG3    DB      '[ More ] ','$'
  124. MSG4    DB      CR,LF,'Not enough memory for buffers',CR,LF,'$'
  125. DATA    ENDS
  126.  
  127. CODE    SEGMENT BYTE PUBLIC
  128.         ASSUME  CS:CODE,DS:DATA,SS:STACK
  129.         EXTRN   SKIPSP:NEAR,UC:NEAR,DECOUT:NEAR,CPYCNT:NEAR,CPY:NEAR
  130.         EXTRN   ERRORMSG:NEAR
  131.         EXTRN   TYPTX:NEAR
  132.         EXTRN   PRINTDD:NEAR
  133.         EXTRN   COUT:NEAR,CIN:NEAR,CLRCO:NEAR,CRLF:NEAR
  134.         EXTRN   FIXPATH:NEAR
  135.  
  136. ;*********************
  137. ; START OF CODE HERE *
  138. ;*********************
  139.  
  140. ENTRY:
  141.         TEST_DOS2                       ;TEST FOR DOS 2.0, EXIT IF DOS 1
  142.         CALL    ALLOC_MEM               ;ALLOCATE MEMORY
  143.         CALL    PARSE_LINE              ;PARSE COMMAND LINE
  144.         CALL    FIND_FILES              ;SEARCH FOR FILES, BUILD LIST IN MEMORY
  145.         CALL    SORT_FILES              ;SORT FILE LIST
  146.         CALL    SHOW_FILES              ;DISPLAY DIRECTORY
  147.         CALL    SHOW_INFO               ;SHOW DISK USAGE INFO
  148.         MOV     AH,EXIT
  149.         INT     DOS                     ;EXIT TO DOS
  150.  
  151. ;*****************************************************
  152. ; ALLOCATE MEMORY FOR BUFFERS, SET ES TO POINT TO IT *
  153. ;*****************************************************
  154.  
  155. ALLOC_MEM PROC NEAR
  156.     MOV    AX,DS
  157.     MOV    ES,AX
  158.     MOV    BX,((1000H+ENDBUF) SHR 4)+1 ;RESERVE SPACE FOR PROGRAM+BUFFERS
  159.     MOV    AH,SET_BLOCK
  160.     INT    DOS
  161.     JB    NOROOM            ;IF ERROR
  162.     MOV    AX,DS            ;GET DATA SEG
  163.     ADD    AX,1000H        ;ADD OFFSET TO BUFFER AREA
  164.     MOV    ES,AX            ;SET EXTRA SEG TO POINT TO BUFFERS
  165.     RET
  166. NOROOM: MOV     AX,DATA                 ;NOT ENOUGH MEMORY
  167.         MOV     DS,AX
  168.         PRINT   MSG4                    ;PRINT MSG
  169.         MOV     AH,EXIT
  170.         INT     DOS                     ;EXIT 2 DOS
  171. ALLOC_MEM ENDP
  172.  
  173. ;***************************************************
  174. ; PARSE COMMAND LINE AND BUILD SEARCH PATH IN SPATH*
  175. ;***************************************************
  176.  
  177. PARSE_LINE  PROC  NEAR
  178.         MOV     BX,OFFSET (80H)          ;POINT TO BYTE COUNT FOR COMMAND LINE
  179.         CMP     BYTE PTR [BX],0         ;FETCH IT
  180.         JNZ     L_1                     ;IF SOMETHING ON COMMAND LINE
  181.         JMP     NONAME
  182. L_1:
  183.         PUSH    BX
  184.         MOV     DL,M
  185.         MOV     DH,0
  186.         ADD     BX,DX
  187.         INC     BX
  188.         MOV     M,0                     ;PUT 0 BYTE AT END OF COMMAND LINE
  189.         POP     BX
  190. SWLOOP:
  191.         INC     BX
  192.     CALL    SKIPSP            ;SKIP LEADING BLANKS
  193.     JB    NOSWITCH
  194.         MOV     AL,M                    ;GET 1ST CHAR.
  195.         CMP     AL,'/'                  ;SWITCH SPECIFIED?
  196.         JE    GOTSW            ;YES
  197.     CMP    AL,'-'            ;CHECK FOR HYPHEN, TOO
  198.     JNE    NOSWITCH
  199. GOTSW:  INC     BX
  200.         MOV     AL,M                    ;GET CHAR. AFTER SWITCH
  201.         CALL    UC                      ;MAKE UPPER-CASE
  202.         CMP     AL,'A'                  ;CHECK FOR A
  203.         JE      ASWITCH                 ;IF GOT A
  204.         CMP     AL,'L'                  ;CHECK FOR L
  205.         JE      LSWITCH                 ;IF GOT L
  206. BADSWITCH:
  207.         SETDS                           ;COME HERE IF BAD SWITCH FOUND
  208.         MOV     BYTE PTR BADSW,AL
  209.         PRINT   MSG1                    ;GIVE BAD SWITCH MSG.
  210.         RESDS
  211.         MOV     AH,EXIT                 ;EXIT TO DOS
  212.         INT     DOS
  213. ASWITCH:
  214.         SETDS
  215.         MOV     BYTE PTR AFLAG,0FFH     ;SET A FLAG
  216.         RESDS
  217.         JMP     SWLOOP                  ;CHECK FOR ANOTHER SWITCH
  218. LSWITCH:
  219.         SETDS
  220.         MOV     BYTE PTR LFLAG,0FFH     ;SET L FLAG
  221.         RESDS
  222.         JMP     SWLOOP                  ;CHECK FOR ANOTHER SWITCH
  223.  
  224. NOSWITCH:
  225.         CALL    SKIPSP                  ;SKIP LEADING BLANKS
  226.         JNC     GOTNAME                 ;IF SOMETHING ON COMMAND LINE
  227.         MOV     AX,DATA
  228.         MOV     DS,AX
  229.         MOV     BX,OFFSET DEFAULT       ;NO NAME SPECIFIED, POINT TO DEFAULT
  230.         JMP     SHORT COPYNAME          ;COPY INTO FILE NAME BUFFER
  231. GOTNAME:
  232.         MOV     AL,[BX+1]               ;SEE IF DRIVE SPECIFIED
  233.         CMP     AL,':'
  234.         JNE     NODRIVE                 ;IF NOT
  235.         MOV     AL,[BX+0]               ;GET DRIVE LETTER
  236.         CALL    UC                      ;MAKE UPPER-CASE
  237.         SETDS
  238.         MOV     BYTE PTR ES:FILNAM,AL   ;SAVE DRIVE LETTER IN FILE NAME BUFFER
  239.         MOV     BYTE PTR ES:(FILNAM+1),':'   ;SAVE COLON ALSO
  240.         SUB     AL,'A'-1                ;CONVERT ASCII TO BINARY (A=1, ETC.)
  241.         MOV     BYTE PTR DRIVE,AL       ;SAVE BINARY DRIVE
  242.         RESDS
  243.         INC     BX                      ;SKIP OVER DRIVE
  244.         INC     BX                      ;AND COLON
  245.         CALL    SKIPSP                  ;ANYTHING AFTER DRIVE SPEC?
  246.         MOV     SI,BX                   ;SAVE START OF FILE NAME, JUST IN CASE
  247.         JNB     DRVPLUSFILE             ;IF FILE NAME GIVEN, COPY INTO NAME BUFFER
  248.         MOV     AX,DATA
  249.         MOV     DS,AX
  250.         MOV     SI,OFFSET DEFAULT       ;ELSE SI POINTS TO DEFAULT FILE NAME
  251. DRVPLUSFILE:
  252.         MOV     DI,OFFSET FILNAM+2      ;DI POINTS TO DESTINATION
  253.         JMP     SHORT COPYNAME2         ;GO COPY FILENAME TO FILE BUFFER
  254. NONAME: MOV     AX,DATA                 ;IF NO NAME, JUST COPY DEFAULT TO FILNAM
  255.         MOV     DS,AX
  256.         MOV     SI,OFFSET DEFAULT
  257.         MOV     DI,OFFSET FILNAM
  258.         JMP     SHORT COPYNAME2
  259. NODRIVE:
  260. COPYNAME:
  261.         MOV     SI,BX                   ;DS:SI POINTS TO START OF NAME
  262.         MOV     DI,OFFSET FILNAM
  263. COPYNAME2:
  264.         MOV     CX,80
  265.         CALL    CPYCNT                  ;SAVE FILE NAME
  266.         PUSH    DS
  267.         MOV     AX,ES
  268.         MOV     DS,AX                   ;MAKE DATA SEG POINT TO BUFFER AREAS
  269.         MOV     BX,OFFSET FILNAM        ;BX - FILE NAME
  270.         MOV     CX,OFFSET SPATH         ;CX - STORAGE FOR SEARCH PATH
  271.         MOV     DX,OFFSET SPREFIX       ;DX - STORAGE FOR SEARCH PREFIX (NOT USED)
  272.         CALL    FIXPATH                 ;PARSE FILE NAME
  273.         POP     DS
  274.         RET
  275. NOFILE:
  276.         PRINT   MSG2
  277.         MOV     AH,EXIT
  278.         INT     DOS
  279. PARSE_LINE  ENDP
  280.  
  281. ;**********************
  282. ; FILE SEARCH ROUTINE *
  283. ;**********************
  284. FIND_FILES PROC NEAR
  285. SETDTA:
  286.         MOV     AX,ES
  287.         MOV     DS,AX                   ;SET DS=ES (WHERE DTA BUFFER IS)
  288.         MOV     DX,OFFSET OUR_DTA       ;LOAD ITS OFFSET
  289.         MOV     AH,SET_DTA
  290.  
  291.         INT     DOS                     ;SET UP DTA
  292.         MOV     AX,DATA
  293.         MOV     DS,AX                   ;RESET DATA SEG.
  294.         MOV     CX,WORD PTR ATTRIBUTES  ;GET DEFAULT ATTRIBUTES
  295.         CMP     BYTE PTR AFLAG,0        ;A FLAG SET?
  296.         JE      SHORT NOAFLAG           ;NO
  297.         OR      CX,00000110B            ;YES, SET SYSTEM & HIDDEN ATTRIBUTES
  298. NOAFLAG:
  299. ;***********************
  300. ; SEARCH FOR 1ST MATCH *
  301. ;***********************
  302.         PUSH    DS
  303.         MOV     AX,ES
  304.         MOV     DS,AX                   ;MAKE DATA SEG = BUFFER SEG
  305.         MOV     DX,OFFSET SPATH         ;POINT TO SEARCH PATH
  306.         MOV     AH,FIND_FIRST
  307.         INT     DOS                     ;SEARCH FOR 1ST MATCH
  308.         POP     DS
  309.         JNC     FOUND1ST                ;IF FOUND
  310.         JMP     NOFILE
  311. ;*********************************************************************
  312. ; COLLECT FILE INFO BLOCKS IN BUFFER, POINTERS TO BLOCKS IN ADDRLIST *
  313. ;*********************************************************************
  314. FOUND1ST:
  315.         MOV     AX,OFFSET BUFFER
  316.         MOV     WORD PTR NEXTFREE,AX
  317. FOUND1: INC     WORD PTR NUMFILES
  318.         CMP     WORD PTR NUMFILES,MAXFILES
  319.         JGE     LASTFILE
  320.         MOV     DI,WORD PTR NEXTFREE
  321.         PUSH    DI
  322.         PUSH    DS
  323.         MOV     AX,ES
  324.         MOV     DS,AX           ;SET DATA SEG = EXTRA SEG
  325.         MOV     SI,OUR_DTA+21
  326.         MOV     CX,22
  327.         CALL    CPY             ;COPY FILE INFO TO TABLE
  328.         POP     DS              ;RESTORE DS
  329.         ADD     WORD PTR NEXTFREE,22
  330.         MOV     AX,NUMFILES
  331.         ADD     AX,AX
  332.         ADD     AX,OFFSET ADDRLIST
  333.         MOV     SI,AX
  334.         POP     BX
  335.         MOV     ES:[SI],BX      ;STORE ADDR IN LIST
  336.         MOV     AH,FIND_NEXT
  337.         INT     DOS             ;FIND NEXT FILE
  338.         JNC     FOUND1          ;LOOP UNTIL NO MORE
  339. LASTFILE:
  340.         RET
  341. FIND_FILES ENDP
  342.  
  343. ;********************************************************
  344. ; SORT POINTERS IN ADDRLIST, USING SHELL SORT ALGORITHM *
  345. ;********************************************************
  346. SORT_FILES PROC NEAR
  347.         MOV     AX,WORD PTR NUMFILES
  348. SORT1:
  349.         SHR     AX,1
  350.         MOV     WORD PTR GAP,AX
  351.         JNZ     SHORT SORT11
  352.         RET                             ;DONE IF GAP = 0
  353. SORT11:
  354.         INC     AX
  355.         MOV     BX,AX
  356. SORT2:  CMP     BX,WORD PTR NUMFILES
  357.         JG      SHORT SORT5
  358.         MOV     CX,BX
  359. SORT3:
  360.         MOV     DX,CX
  361.         SUB     CX,WORD PTR GAP
  362.         JBE     SHORT SORT4
  363.         CALL    COMPARE                 ;COMPARE ADDRLIST[DX], ADDRLIST[CX]
  364.         JLE     SHORT SORT4
  365.         CALL    SWAP
  366.         JMP     SORT3
  367. SORT4:
  368.         INC     BX
  369.         JMP     SORT2
  370. SORT5:
  371.         MOV     AX,WORD PTR GAP
  372.         JMP     SORT1
  373. SORT_FILES ENDP
  374.  
  375. COMPARE PROC    NEAR
  376.         PUSH    BX
  377.         PUSH    CX
  378.         PUSH    DS
  379.         MOV     AX,ES
  380.         MOV     DS,AX
  381.         MOV     SI,CX
  382.         ADD     SI,SI
  383.         ADD     SI,OFFSET ADDRLIST
  384.         MOV     AX,ES:[SI]
  385.         ADD     AX,9
  386.         MOV     SI,AX
  387.         MOV     DI,DX
  388.         ADD     DI,DI
  389.         ADD     DI,OFFSET ADDRLIST
  390.         MOV     AX,ES:[DI]
  391.         ADD     AX,9
  392.         MOV     DI,AX
  393.         MOV     CX,11
  394.         REPE    CMPSB
  395.         POP     DS
  396.         POP     CX
  397.         POP     BX
  398.         RET
  399. COMPARE ENDP
  400.  
  401. SWAP    PROC    NEAR
  402.         PUSH    BX
  403.         MOV     SI,CX
  404.         ADD     SI,SI
  405.         ADD     SI,OFFSET ADDRLIST
  406.         MOV     BX,ES:[SI]
  407.         MOV     DI,DX
  408.         ADD     DI,DI
  409.         ADD     DI,OFFSET ADDRLIST
  410.         MOV     AX,ES:[DI]
  411.         MOV     ES:[SI],AX
  412.         MOV     ES:[DI],BX
  413.         POP     BX
  414.         RET
  415. SWAP    ENDP
  416.  
  417. ;********************
  418. ; DISPLAY DIRECTORY *
  419. ;********************
  420. SHOW_FILES PROC NEAR
  421.         IF      IBM
  422.         MOV     AH,15
  423.         INT     BIOS                    ;GET VIDEO MODE
  424.         MOV     BYTE PTR VPAGE,BH       ;STORE VIDEO PAGE #
  425.         MOV     BYTE PTR SCRSIZE,AH     ;STORE CHARS/LINE
  426.         MOV     BYTE PTR VMODE,AL       ;STORE DISPLAY MODE
  427.         ENDIF
  428.         MOV     SI,OFFSET ADDRLIST
  429.         MOV     WORD PTR BASE,1
  430.         MOV     BYTE PTR MAXCOL,NCOLUMN ;INITIALIZE MAXCOL FOR SHORT DISPLAY
  431.         CMP     BYTE PTR LFLAG,0        ;LONG DISPLAY FLAG SET?
  432.         JE      DISP1                   ;NO, KEEP MAXCOL INTACT
  433.         MOV     BYTE PTR MAXCOL,2       ;YES, USE 2 COLUMNS
  434. DISP1:
  435.         MOV     BL,BYTE PTR MAXCOL
  436.         MOV     AL,MAXLINES
  437.         MUL     BL                      ;COMPUTE (MAXLINES)*MAXCOL
  438.         ADD     AX,WORD PTR BASE        ;ADD BASE TO GET LAST FILE # WE
  439.                                         ;CAN SHOW ON THIS SCREEN
  440.         MOV     BX,AX
  441.         MOV     AX,WORD PTR NUMFILES    ;COMPARE WITH TOTAL # FILES
  442.         SUB     AX,BASE                 ;-BASE
  443.         INC     AX                      ;+1
  444.         CMP     AX,BX                   ;WILL ALL FILES FIT ON SCREEN?
  445.         JG      DISP3                   ;NO
  446.         MOV     BL,BYTE PTR MAXCOL
  447.         DIV     BL                      ;YES, COMPUTE # OF LINES/COLUMN
  448.         CMP     AH,0                    ;IS REMAINDER 0?
  449.         JE      DISP2                   ;YES, SKIP AHEAD
  450.         INC     AL                      ;NO, ADD 1 TO LINE COUNT
  451. DISP2:  MOV     AH,0                    ;ZERO HI BYTE OF LINES/COLUMN
  452.         MOV     WORD PTR MAXLINE,AX     ;MAXLINE=# OF LINES TO SHOW IN
  453.                                         ;THIS SCREEN
  454.         MOV     AX,WORD PTR NUMFILES    ;NUMBER OF FILES THERE ARE
  455.         MOV     WORD PTR MAXFILE,AX     ;=LAST FILE # TO DISPLAY
  456.         JMP     SHORT DISP4
  457. DISP3:  MOV     AX,MAXLINES             ;TOO MANY FILES FOR 1 SCREEN, SO
  458.         MOV     WORD PTR MAXLINE,AX     ;USE WHOLE SCREEN FOR DISPLAY
  459.         MOV     AL,MAXLINES
  460.         MOV     BL,BYTE PTR MAXCOL
  461.         MUL     BL                      ;COMPUTE MAX. FILES/SCREEN
  462.         MOV     WORD PTR MAXFILE,AX     ;STORE AS # OF FILES TO SHOW
  463. DISP4:
  464.         MOV     WORD PTR COLCOUNT,1     ;START AT COLUMN 1
  465.         MOV     WORD PTR LINECOUNT,1    ;AND LINE 1
  466.         MOV     WORD PTR FILECOUNT,0    ;# OF FILES DISPLAYED IN THIS SCREEN
  467. DISP5:
  468.         MOV     CX,1                    ;CX WILL COUNT UP TO COLCOUNT
  469.         MOV     BX,0                    ;BX WILL HOLD (CX-1)*MAXLINE
  470. DISP6:                                  ;COMPUTE (COLCOUNT-1)*MAXLINE
  471.         CMP     CX,WORD PTR COLCOUNT
  472.         JGE     DISP7
  473.         ADD     BX,WORD PTR MAXLINE
  474.         INC     CX
  475.         JMP     DISP6
  476. DISP7:
  477.         ADD     BX,WORD PTR LINECOUNT   ;ADD LINE COUNT
  478.         DEC     BX                      ;-1
  479.         ADD     BX,BASE                 ;ADD TO BASE
  480.         CMP     BX,WORD PTR NUMFILES    ;BLANK SLOT IN LAST COLUMN?
  481.         JG      DISP9                   ;YUP.
  482.         CMP     WORD PTR COLCOUNT,1     ;1ST COLUMN?
  483.         JE      DISP8                   ;YES, NO FENCE
  484.         CALL    DOFENCE                 ;SHOW FENCE
  485. DISP8:
  486.         ADD     BX,BX                   ;DOUBLE FILE # TO GET OFFSET TO ADDR.
  487.                                         ;OF FILE INFO
  488.         MOV     DI,ES:[SI+BX]           ;GET ADDRESS OF FILE INFO
  489.         CALL    SHOW                    ;SHOW A FILE
  490.         CALL    BUMPCOL                 ;UPDATE LINE & COLUMN COUNTS
  491.         INC     WORD PTR FILECOUNT      ;BUMP FILE COUNT
  492.         MOV     AX,WORD PTR FILECOUNT   ;GET IT
  493.         CMP     AX,WORD PTR MAXFILE     ;DONE ALL FILES?
  494.         JGE     DISP11                  ;IF DONE
  495.         JMP     SHORT DISP10
  496. DISP9:
  497.         CALL    BUMPCOL
  498. DISP10:
  499.         MOV     AX,WORD PTR LINECOUNT   ;GET LINE COUNT
  500.         CMP     AX,WORD PTR MAXLINE     ;IS IT >MAX LINE?
  501.         JLE     DISP5                   ;IF NOT
  502.  
  503. ;       COME HERE WHEN SCREEN IS FULL OR ALL FILES DONE:
  504. DISP11:
  505.         CMP     WORD PTR COLCOUNT,1     ;IS COLUMN COUNT =1?
  506.         JLE     NOADDCR                 ;YES, NO CR NEEDED
  507.         CALL    CRLF                    ;NO, SHOW CR AFTER LAST LINE
  508. NOADDCR:
  509.         MOV     AX,WORD PTR BASE
  510.         ADD     AX,WORD PTR MAXFILE
  511.         MOV     WORD PTR BASE,AX        ;GET BASE FOR NEXT SCREEN
  512.         MOV     BX,AX
  513.         MOV     AX,WORD PTR NUMFILES
  514.         SUB     AX,BX                   ;COMPUTE # FILES REMAINING
  515.         JBE     ENDDISP                 ;IF NO MORE
  516.         CALL    WAITCR                  ;WAIT FOR USER
  517.         JMP     DISP1                   ;DO NEXT SCREEN
  518. ENDDISP:
  519.     CMP    WORD PTR LINECOUNT,MAXLINES-1 ;IS SCREEN FULL (OR NEARLY SO)?
  520.     JL    NOWAIT
  521.     CALL    WAITCR            ;YES, WAIT (SO INFO LINE DOESN'T CAUSE
  522.                     ;LOSS OF TOP DISPLAY LINE)
  523. NOWAIT:
  524.         RET
  525. SHOW_FILES ENDP
  526.  
  527. BUMPCOL PROC    NEAR
  528.         INC     WORD PTR COLCOUNT       ;BUMP COLUMN COUNT
  529.         MOV     AX,WORD PTR COLCOUNT
  530.         CMP     AL,BYTE PTR MAXCOL      ;PAST LAST COLUMN?
  531.         JLE     BC1                     ;NO, KEEP GOING
  532.         CALL    CRLF                    ;YES, START NEW LINE
  533.         MOV     WORD PTR COLCOUNT,1     ;RESET COLUMN COUNTER
  534.         INC     WORD PTR LINECOUNT      ;UPDATE LINE COUNTER
  535. BC1:
  536.         RET
  537. BUMPCOL ENDP
  538.  
  539. DOFENCE PROC    NEAR                    ;SHOW "FENCE" BETWEEN COLUMNS
  540.         CMP     BYTE PTR LFLAG,0        ;L FLAG SET?
  541.         JE      SHORTFENCE              ;NO.
  542.         CALL    TYPTX                   ;YES, LONGER GAP BTWN. COLUMNS
  543.         DB      SPACE,SPACE+200Q
  544.     MOV    AX,FENCE
  545.         CALL    COUT
  546.     CALL    TYPTX
  547.     DB    SPACE,SPACE+200Q
  548.         RET
  549. SHORTFENCE:
  550.         MOV    AX,SPACE
  551.     CALL    COUT
  552.     MOV    AX,FENCE
  553.     CALL    COUT
  554.     MOV    AX,SPACE
  555.     CALL    COUT
  556.         RET
  557. DOFENCE ENDP
  558.  
  559. ;       SHOW FILE NAME, SIZE (DI POINTS TO INFO)
  560. ;
  561. SHOW    PROC    NEAR
  562.         PUSH    DI
  563.         MOV     CX,8
  564. SHOWNAME:                               ;SHOW FILE NAME
  565.         MOV     AL,ES:[DI+9]            ;GET CHAR.
  566.         CMP     AL,'.'
  567.         JE      GOTDOT                  ;DOT MEANS END OF NAME
  568.         CMP     AL,0
  569.         JE      SHOWEXT                 ;SO DOES NULL
  570.         CALL    COUT                    ;SHOW CHAR.
  571.         INC     DI                      ;BUMP POINTER
  572.         DEC     CX                      ;DEC COUNT
  573.         JMP     SHOWNAME                ;LOOP
  574. GOTDOT: PUSH    AX                      ;FOUND END OF NAME, UNUSED COUNT IN CX
  575.         CALL    SPOUT                   ;WRITE CX SPACES
  576.         POP     AX
  577.         CALL    COUT                    ;NOW WRITE DOT
  578.         INC     DI                      ;POINT PAST DOT
  579.         JMP     SHORT SHOW3
  580. SHOWEXT: INC    CX                      ;HAVE NO EXTENSION
  581.         CALL    SPOUT                   ;PAD OUT NAME FIELD
  582. SHOW3:  MOV     CX,3                    ;PREPARE TO SHOW EXTENSION (3 CHARS.)
  583. SHOW4:  MOV     AL,ES:[DI+9]            ;GET CHAR.
  584.         CMP     AL,0
  585.         JE      SHOW5                   ;DONE IF NULL
  586.         CALL    COUT                    ;SHOW CHAR.
  587.         INC     DI                      ;BUMP POINTER
  588.         LOOP    SHOW4                   ;LOOP
  589. SHOW5:  CALL    SPOUT                   ;PRINT A SPACE
  590. SHOW6:  POP     DI                      ;POINT TO START OF INFO AGAIN
  591.         MOV     AL,ES:[DI]              ;GET FILE ATTRIBUTE
  592.         AND     AL,00010000B            ;IS IT A DIRECTORY?
  593.         JZ      SHOW7                   ;NO.
  594.         CMP     BYTE PTR LFLAG,0        ;LONG DISPLAY?
  595.         JE      SHOW6A                  ;NO
  596.         MOV     CX,3                    ;YES, 3 EXTRA SPACES
  597.         CALL    SPOUT
  598.  
  599. SHOW6A:                                 ;HAVE DIRECTORY
  600.         CALL    TYPTX
  601.         DB      '<DIR','>'+80H          ;SAY IT'S A DIR
  602.         CMP     BYTE PTR LFLAG,0        ;IS L FLAG SET?
  603.         JNE     SHOW8A                  ;YES, FINISH UP
  604.         RET                             ;NO, ALL DONE
  605.  
  606. SHOW7:                                  ;HAVE FILE, NOT DIR
  607.         MOV     AX,ES:[DI+5]            ;LSW OF FILE SIZE
  608.         MOV     DX,ES:[DI+7]            ;MSW OF FILE SIZE
  609.         ADD     AX,WORD PTR USED        ;ADD LSW OF FILE SIZE TO
  610.                                         ;LSW OF USED COUNT
  611.         MOV     WORD PTR USED,AX
  612.         ADC     WORD PTR USED+2,DX      ;NOW ADD MSW
  613.         CMP     BYTE PTR LFLAG,0        ;L FLAG SET?
  614.         JNE     SHOW8                   ;YES, LONG DISPLAY
  615.         MOV     AX,ES:[DI+5]            ;SHORT DISPLAY, GET LSW FILE SIZE
  616.         CALL    MAKEK                   ;CONVERT TO KBYTES
  617.         MOV     AL,SPACE                ;WITH LEADING SPACES,
  618.         MOV     CX,4                    ;AND FIELD WIDTH = 4,
  619.         CALL    DECOUT                  ;SHOW FILE SIZE
  620.         MOV     AL,'K'
  621.         CALL    COUT                    ;SHOW LETTER K
  622.         RET                             ;DONE
  623.  
  624. SHOW8:  MOV     AX,ES:[DI+5]            ;LONG DISPLAY
  625.         PUSH    SI                      ;MOVE SIZE TO DI:SI
  626.         MOV     SI,AX
  627.         MOV     AX,ES:[DI+7]
  628.         PUSH    DI
  629.         MOV     DI,AX
  630.         MOV     AL,SPACE                ;WITH LEADING SPACES,
  631.         CALL    PRINTDD                 ;SHOW FILE SIZE IN BYTES
  632.         POP     DI
  633.         POP     SI
  634. SHOW8A:
  635.         MOV     CX,2
  636.         CALL    SPOUT                   ;PRINT 2 SPACES
  637.         MOV     AX,ES:[DI+3]            ;GET PACKED DATE
  638.         CALL    PRTDTE                  ;SHOW IT
  639.         MOV     CX,2
  640.         CALL    SPOUT                   ;PRINT 2 SPACES
  641.         MOV     AX,ES:[DI+1]            ;GET PACKED TIME
  642.         CALL    PRTTME                  ;SHOW IT
  643.         RET                             ;DONE
  644. SHOW    ENDP
  645.  
  646. ;       SUBROUTINE - WRITES CX SPACES TO SCREEN
  647.  
  648. SPOUT   PROC    NEAR
  649.         JCXZ    SPOUT1
  650.         MOV     AL,SPACE
  651.         CALL    COUT
  652.         DEC     CX
  653.         JMP     SPOUT
  654. SPOUT1: RET
  655. SPOUT   ENDP
  656.  
  657. ;       SUBROUTINE - PAUSES AT END OF SCREEN
  658.  
  659. WAITCR  PROC    NEAR
  660.         PRINT   MSG3            ;PROMPT USER FOR OK TO SHOW NEXT SCREEN
  661.         CALL    CLRCO           ;CLEAR TYPE-AHEAD
  662.         CALL    CIN             ;GET A CHAR.
  663.         CALL    CLRSCR          ;CLEAR SCREEN
  664.         RET
  665. WAITCR  ENDP
  666.  
  667. ;       ROUTINE TO CLEAR SCREEN, HOME CURSOR:
  668. ;       (MAY HAVE TO CHANGE FOR NON-IBM MACHINES)
  669.  
  670. CLRSCR  PROC    NEAR
  671.         PUSH    BX
  672.         IF      IBM
  673.         MOV     DX,0
  674.         CALL    MOVEXY                  ;MOVE TO HOME POSITION
  675.         MOV     AL,BYTE PTR DATA:VMODE  ;GET CURRENT VIDEO MODE
  676.         MOV     AH,0
  677.         INT     BIOS                    ;RESET MODE (CLEARS SCREEN)
  678.         ELSE
  679.         MOV     AL,FF                   ;NON-IBM CLEAR SCREEN
  680.         CALL    COUT                    ;USE FF (WILL WORK ON MOST TERMINALS)
  681.         ENDIF
  682.         POP     BX
  683.         RET
  684. CLRSCR  ENDP
  685.  
  686. MOVEXY  PROC    NEAR                    ;MOVE TO ROW (DH) AND COLUMN (DL)
  687.         MOV     AH,2
  688.         MOV     BH,BYTE PTR VPAGE       ;VIDEO PAGE #
  689.         MOV     BL,0                    ;COLOR (DON'T CHANGE)
  690.         INT     BIOS                    ;MOVE CURSOR
  691.         RET
  692. MOVEXY  ENDP
  693.  
  694. ;**************************************************
  695. ; DISPLAY NUMBER OF FILES, SPACE USED, SPACE FREE *
  696. ;**************************************************
  697. SHOW_INFO PROC NEAR
  698.         MOV     BX,WORD PTR NUMFILES    ;GET NUMBER OF FILES
  699.         MOV     AL,0                    ;SUPPRESS LEADING 0'S
  700.         MOV     CX,5                    ;FIELD WIDTH = 5
  701.         CALL    DECOUT                  ;SHOW # FILES
  702.         CALL    TYPTX
  703.         DB      ' files, using',SPACE+80H
  704.         CMP     BYTE PTR LFLAG,0        ;L FLAG SET?
  705.         JE      INFO1                   ;NO, SHORT DISPLAY
  706.         MOV     DI,WORD PTR USED+2
  707.         MOV     SI,WORD PTR USED        ;GET SPACE USED IN SI:DI
  708.         MOV     AL,0                    ;SUPPRESS LEADING 0'S
  709.         CALL    PRINTDD                 ;SHOW SPACE USED
  710.         CALL    TYPTX
  711.         DB      ' bytes ','('+200Q
  712.         JMP     SHORT INFO2
  713. INFO1:                                  ;SHORT DISPLAY
  714.         MOV     AX,WORD PTR USED
  715.         MOV     DX,WORD PTR USED+2      ;GET AMT. USED IN DX:AX
  716.         CALL    MAKEK                   ;CONVERT TO K
  717.         MOV     AL,0                    ;SUPPRESS LEADING 0'S
  718.         MOV     CX,5                    ;FIELD WIDTH = 5
  719.         CALL    DECOUT                  ;SHOW AMT. USED
  720.         MOV     AL,'K'
  721.         CALL    COUT                    ;SHOW LETTER K
  722. INFO2:
  723.         MOV     AH,CURRENT_DISK
  724.         INT     DOS                     ;GET CURRENT DISK
  725.         PUSH    AX                      ;SAVE IT
  726.         MOV     DL,BYTE PTR DRIVE       ;DL = DRIVE WE SPECIFIED
  727.         CMP     DL,0                    ;CURRENT DISK?
  728.         JE      NOCHANGE                ;YES, NO NEED TO CHANGE
  729.         INC     AL
  730.         CMP     AL,DL                   ;SAME AS CURRENT DISK?
  731.         JE      NOCHANGE                ;YES, NO NEED TO CHANGE
  732.         DEC     DL                      ;MAKE 0=A, ETC.
  733.         MOV     AH,SELECT_DISK
  734.         INT     DOS                     ;SELECT DISK
  735. NOCHANGE:
  736.         MOV     DL,0                    ;NOW USING CURRENT DISK,
  737.         MOV     AH,GET_FREE_SPACE
  738.         INT     DOS                     ;GET FREE SPACE
  739.         MUL     BX                      ;COMPUTE # SECTORS FREE
  740.         PUSH    DX                      ;SAVE HI WORD
  741.         MUL     CX                      ;MULTIPLY LO WORD OF SECTOR COUNT
  742.                                         ;BY BYTES/SECTOR
  743.         MOV     LOSIZE,AX               ;SAVE LO WORD OF FREE SPACE
  744.         POP     BX                      ;GET HI WORD OF SECTOR COUNT
  745.         PUSH    DX                      ;SAVE CARRY FROM LO WORD MULT.
  746.         MOV     AX,BX                   ;MULTIPLICAND IN AX
  747.         MUL     CX                      ;MULTIPLY HI WORD OF SECTOR COUNT
  748.                                         ;TIMES BYTES/SECTOR
  749.         POP     BX                      ;GET CARRY FROM LO WORD
  750.         ADD     AX,BX                   ;ADD IT
  751.         MOV     DX,AX                   ;DX = HI WORD OF FREE SPACE
  752.         MOV     AX,LOSIZE               ;AX = LO WORD OF FREE SPACE
  753.         CMP     BYTE PTR LFLAG,0        ;L FLAG SET?
  754.         JE      INFO3                   ;NO, SHORT DISPLAY
  755.         MOV     DI,DX                   ;LONG DISPLAY,
  756.         MOV     SI,AX                   ;MOVE AMT. FREE TO DI:SI
  757.         MOV     AL,0                    ;SUPPRESS LEADING 0'S
  758.         CALL    PRINTDD                 ;SHOW AMT. FREE
  759.         CALL    TYPTX
  760.         DB      ' bytes free',')'+200Q
  761.         JMP     SHORT INFO4
  762. INFO3:                                  ;SHORT DISPLAY
  763.         MOV     CX,K                    ;CX = 1 K
  764.         DIV     CX                      ;DIVIDE TO GET KBYTES FREE
  765.         MOV     BX,AX                   ;SAVE IT
  766.         MOV     AL,SPACE
  767.         CALL    COUT                    ;WRITE SPACE
  768.         MOV     AL,'('
  769.         CALL    COUT                    ;WRITE PAREN
  770.         MOV     AL,0                    ;MEANS NO LEADING 0'S
  771.         MOV     CX,5                    ;5 DIGITS MAX.
  772.         CALL    DECOUT                  ;SHOW SPACE FREE
  773.         CALL    TYPTX
  774.         DB      'K free',')'+80H
  775. INFO4:
  776.         CALL    CRLF                    ;SHOW CR/LF
  777.         POP     DX
  778.         MOV     AH,SELECT_DISK          ;RESET DEFAULT DISK
  779.         INT     DOS
  780.         RET                             ;DONE
  781. SHOW_INFO ENDP
  782.  
  783. ;       MAKEK = TAKE QUAD # IN DX:AX, CONVERT TO K IN BX
  784.  
  785. MAKEK   PROC    NEAR
  786.         MOV     BX,K
  787.         DIV     BX                      ;DIVIDE TO GET SIZE IN K
  788.         MOV     BX,AX                   ;QUOTIENT IN BX
  789.         CMP     DX,0                    ;MODULUS>0?
  790.         JE      NOROUND
  791.         INC     BX                      ;IF SO, ROUND UP
  792. NOROUND:
  793.         RET
  794. MAKEK   ENDP
  795.  
  796. ;       The following two routines are adapted from SDIR Version
  797. ;       2.4, by Ted Reuss (modified from a program by John Chapman), on
  798. ;       PC-SIG Volume 185.
  799.  
  800.         SUBTTL  PRINT DATE, TIME & # FILES ROUTINES
  801.         PAGE
  802.  
  803. ; PC-DOS packed date   <yyyyyyym mmmddddd>
  804. P_DTE       RECORD  P_YR:7,P_MO:4,P_DY:5
  805. ; PC-DOS packed time   <hhhhhmmm mmmsssss>
  806. P_TME       RECORD  P_HR:5,P_MI:6,P_2S:5
  807.  
  808. PRTDTE  PROC    NEAR    ;Print packed date in AX as MM/DD/YY
  809.         OR      AX,AX
  810.         JNZ     K1              ;If date <> 0
  811.         MOV     CX,8
  812.         CALL    SPOUT            ;Print 8 spaces
  813.         RET
  814. K1:     PUSH    AX
  815.         AND     AX,MASK P_MO    ;Mask the month,
  816.         MOV     CL,P_MO         ; set shift count,
  817.         SHR     AX,CL           ; right justify, &
  818.         CALL    PRTBCD          ; print it.
  819.         MOV     AX,'/'
  820.         CALL    COUT
  821.         POP     AX
  822.         PUSH    AX
  823.         AND     AX,MASK P_DY    ;Mask the day &
  824.         CALL    PRTBCD          ; print it.
  825.         MOV     AX,'/'
  826.         CALL    COUT
  827.         POP     AX
  828.         AND     AX,MASK P_YR    ;Mask the year,
  829.         MOV     CL,P_YR         ; set shift count,
  830.         SHR     AX,CL           ; right justify,
  831.         ADD     AX,80           ; add in year bias, &
  832.                                 ; print it.
  833. PRTBCD: AAM                     ;Convert AL to BCD
  834.         OR      AX,'00'         ;Convert to ASCII
  835.         PUSH    AX
  836.         MOV     AL,AH
  837.         CALL    COUT            ;High order digit
  838.         POP     AX
  839.         CALL    COUT            ;Low order digit
  840.         RET
  841. PRTDTE  ENDP
  842.  
  843. PRTTME  PROC    NEAR            ;Print packed time in AX as HH:MM
  844.         OR      AX,AX
  845.         JNZ     L1              ;if date<>0
  846.         MOV     CX,5
  847.         CALL    SPOUT           ;Print 5 spaces
  848.         RET
  849. L1:     PUSH    AX
  850.         AND     AX,MASK P_HR    ;Mask the hours,
  851.         MOV     CL,P_HR         ; set shift count,
  852.         SHR     AX,CL           ; right justify, &
  853.         CALL    PRTBCD          ; print it.
  854.         MOV     AX,':'
  855.         CALL    COUT
  856.         POP     AX
  857.         AND     AX,MASK P_MI    ;Mask the minutes,
  858.         MOV     CL,P_MI         ; set shift count,
  859.         SHR     AX,CL           ; right justify, &
  860.         CALL    PRTBCD          ; print it.
  861.         RET
  862. PRTTME  ENDP
  863.  
  864. CODE    ENDS
  865.         END     ENTRY
  866.  
  867.